set_xen_guest_handle(reservation.extent_start, &gmfn);
ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
&reservation);
+ if (ret == -ENOSYS)
+ goto err;
BUG_ON(ret != 1);
} else {
ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
dealloc_pte_fn, NULL);
+ if (ret == -ENOSYS)
+ goto err;
BUG_ON(ret);
}
current_pages -= 1UL << order;
set_page_count(page + i, 1);
return page;
+
+ err:
+ free_pages(vstart, order);
+ balloon_unlock(flags);
+ return NULL;
}
void balloon_dealloc_empty_page_range(
return -ENODEV;
mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
+
+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
+ extern unsigned long alloc_empty_foreign_map_page_range(
+ unsigned long pages);
+ mmap_vstart = (unsigned long)
+ alloc_empty_foreign_map_page_range(mmap_pages);
+#else /* ! ia64 */
+ page = balloon_alloc_empty_page_range(mmap_pages);
+ if (page == NULL)
+ return -ENOMEM;
+ mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+#endif
+
pending_reqs = kmalloc(sizeof(pending_reqs[0]) *
blkif_reqs, GFP_KERNEL);
pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
blkif_interface_init();
-#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
- extern unsigned long alloc_empty_foreign_map_page_range(
- unsigned long pages);
- mmap_vstart = (unsigned long)
- alloc_empty_foreign_map_page_range(mmap_pages);
-#else /* ! ia64 */
- page = balloon_alloc_empty_page_range(mmap_pages);
- BUG_ON(page == NULL);
- mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
-#endif
printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
__FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
BUG_ON(mmap_vstart == 0);
/******************************************************************
* misc small helpers
*/
-/* FIXME: Return ENOMEM properly on failure to allocate additional reqs. */
-static void req_increase(void)
+static int req_increase(void)
{
int i, j;
struct page *page;
unsigned long flags;
+ int ret;
spin_lock_irqsave(&pending_free_lock, flags);
+ ret = -EINVAL;
if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock)
goto done;
- pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) *
- blkif_reqs, GFP_KERNEL);
- pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
- mmap_pages, GFP_KERNEL);
-
- if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
- kfree(pending_reqs[mmap_alloc]);
- kfree(pending_addrs[mmap_alloc]);
- WPRINTK("%s: out of memory\n", __FUNCTION__);
- goto done;
- }
-
#ifdef __ia64__
extern unsigned long alloc_empty_foreign_map_page_range(
unsigned long pages);
alloc_empty_foreign_map_page_range(mmap_pages);
#else /* ! ia64 */
page = balloon_alloc_empty_page_range(mmap_pages);
- BUG_ON(page == NULL);
+ ret = -ENOMEM;
+ if (page == NULL) {
+ printk("%s balloon_alloc_empty_page_range gave NULL\n", __FUNCTION__);
+ goto done;
+ }
/* Pin all of the pages. */
for (i=0; i<mmap_pages; i++)
mmap_start[mmap_alloc].mpage = page;
#endif
+
+ pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) *
+ blkif_reqs, GFP_KERNEL);
+ pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
+ mmap_pages, GFP_KERNEL);
+
+ ret = -ENOMEM;
+ if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
+ kfree(pending_reqs[mmap_alloc]);
+ kfree(pending_addrs[mmap_alloc]);
+ WPRINTK("%s: out of memory\n", __FUNCTION__);
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ ret = 0;
+
DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
__FUNCTION__, blkif_reqs, mmap_pages,
mmap_start[mmap_alloc].start);
DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
done:
spin_unlock_irqrestore(&pending_free_lock, flags);
-
+ return ret;
}
static void mmap_req_del(int mmap)
return -ENODEV;
INIT_LIST_HEAD(&pending_free);
- for(i = 0; i < 2; i++) req_increase();
+ for(i = 0; i < 2; i++) {
+ ret = req_increase();
+ if (ret)
+ break;
+ }
+ if (i == 0)
+ return ret;
tap_blkif_interface_init();